﻿namespace KinonekoSoftware.Foundation.UI.Controls.TextBox
{
    public class NumericTextBox : ForestTextBoxBase
    {
          private ForestRepeatButtonBase _Up;
        private ForestRepeatButtonBase _Down;
        private int                    _Number;


        public static readonly DependencyProperty ValueProperty = DependencyProperty.Register(
            nameof(Value),
            typeof(int),
            typeof(NumericTextBox),
            new PropertyMetadata(default(int), OnValueChanged));


        public static readonly DependencyProperty MaximumProperty = DependencyProperty.Register(
            nameof(Maximum),
            typeof(int),
            typeof(NumericTextBox),
            new PropertyMetadata(100));

        public static readonly DependencyProperty MinimumProperty = DependencyProperty.Register(
            nameof(Minimum),
            typeof(int),
            typeof(NumericTextBox),
            new PropertyMetadata(0));

        public NumericTextBox()
        {
            Text = "0";
        }


        private static void OnValueChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            ((NumericTextBox)d).Text = ((int)e.NewValue).ToString();
        }

        protected override void OnGotFocus(RoutedEventArgs e)
        {
            if(!string.IsNullOrEmpty(Text))
                Select(0, Text.Length);
            base.OnGotFocus(e);
        }

        private void UpdateValue(int value)
        {
            var expression = BindingOperations.GetBindingExpression(this, ValueProperty);

            SetValue(ValueProperty, value);
            
            if (expression is not null)
            {
                expression.UpdateSource();
                expression.UpdateTarget();
            }
        }

        public override void OnApplyTemplate()
        {
            if (GetTemplateChild("PART_UpButton") is ForestRepeatButtonBase up)
            {
                _Up = up;
                _Up.Click += OnUp;
            }
            
            if (GetTemplateChild("PART_DownButton") is ForestRepeatButtonBase down)
            {
                _Down       =  down;
                _Down.Click += OnDown;
            }
            
            base.OnApplyTemplate();
        }

        protected override void OnTextChanged(TextChangedEventArgs e)
        {
            base.OnTextChanged(e);
            _Number = Math.Clamp(int.TryParse(Text, out var n) ? n : 0, Minimum, Maximum);
            UpdateValue(_Number);
            Text = _Number.ToString();
        }

        private void OnUp(object sender, RoutedEventArgs e)
        {
            _Number     = Math.Min(_Number + 1, Maximum);
            Text        = _Number.ToString();
            UpdateValue(_Number);
        }
        
        
        private void OnDown(object sender, RoutedEventArgs e)
        {
            _Number = Math.Max(_Number - 1, Minimum);
            Text    = _Number.ToString();
            UpdateValue(_Number);
        }

        public int Value
        {
            get => (int)GetValue(ValueProperty);
            set => SetValue(ValueProperty, value);
        }
        
        public int Minimum
        {
            get => (int)GetValue(MinimumProperty);
            set => SetValue(MinimumProperty, value);
        }
        
        
        public int Maximum
        {
            get => (int)GetValue(MaximumProperty);
            set => SetValue(MaximumProperty, value);
        }
    }
}